package mx.com.sinformex.simbel.pages.reports;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;

import mx.com.sinformex.simbel.db.dao.IReportDataAccess;
import mx.com.sinformex.simbel.db.eos.Report;
import mx.com.sinformex.simbel.db.eos.ReportParam;
import mx.com.sinformex.simbel.pages.BasicPage;
import mx.com.sinformex.simbel.utils.IFileReporteExporter;
import mx.com.sinformex.simbel.utils.XmlStreamResponse;
import mx.com.sinformex.simbel.utils.export.CsvExporter;
import mx.com.sinformex.simbel.utils.export.JasperExporter;
import mx.com.sinformex.simbel.utils.export.XlsExporter;

/**
 * @author Oscar Ivan Hernandez Ventura [ oscar at sinformex dot com dot mx]
 *
 * @version $ Id : ViewReport.java , v 1.0 12/05/2009 angellore $
 */
public class ViewReport extends BasicPage {
	
	@Persist
	private Report report;
	@Property
	private ReportParam param;
	@Inject
	private HttpServletRequest request;
	@Inject
	private IReportDataAccess reportDataAccess;
	@Persist
	private List<Map<String,Object>> rows;
	private final Log log = LogFactory.getLog(getClass());
	
	public Report getReport() {
		return report;
	}

	public void setReport(Report report) {
		this.report = report;
	}
	
	@SuppressWarnings("unchecked")
	StreamResponse onActionFromSubmitLink() {
		List<Object> args= new ArrayList<Object>();		
		String params = request.getParameter("args");
		String p = request.getParameter("currentPage");
		
		//If report have to use jasper file, then, stream the parsed template
		if(report.getJasperReportFileName() != null) {
			return onActionFromExportJasper();
		}
		
		int currentPage = 0;
		if(p == null) {
			log.info("Loading data from database");
			if(params != null) {
				StringTokenizer tokenizer = new StringTokenizer(params, "@@");
				while(tokenizer.hasMoreElements()) {
					StringTokenizer tokenizer2 = new StringTokenizer(tokenizer.nextToken(), "\\|\\|\\|\\|");
					tokenizer2.nextElement();
					args.add(tokenizer2.nextElement());
				}
			}

			try {
				rows = reportDataAccess.executeFullReport(report, args.toArray());
			} catch (Exception e) {
				e.printStackTrace();
				return new XmlStreamResponse(java.util.Collections.EMPTY_LIST, 0, e.getMessage().replaceAll("'", ""));
			}
		} else {
			currentPage = Integer.parseInt(p);
			log.info(String.format("Loading page %d from cache", currentPage));
		}

		return new XmlStreamResponse(rows, currentPage, null);
	}
	
	StreamResponse onActionFromExportxls() {		
		String params = request.getParameter("args");
		List<Object> args= new ArrayList<Object>();
		
		if(params != null) {
			StringTokenizer tokenizer = new StringTokenizer(params, "@@");
			while(tokenizer.hasMoreElements()) {
				StringTokenizer tokenizer2 = new StringTokenizer(tokenizer.nextToken(), "\\|\\|\\|\\|");
				tokenizer2.nextElement();
				args.add(tokenizer2.nextElement());
			}
		}	
		 
		List<Map<String, Object>> rows;
		try {
			rows = reportDataAccess.executeFullReport(report, args.toArray());
			IFileReporteExporter exporter = new XlsExporter();
			return exporter.export(rows, null, null, null, report.getName());
		} catch (Exception e) {
			e.printStackTrace();
			setError(e.getMessage());
		}
		
		return null;
	}	
	
	StreamResponse onActionFromExportJasper() {		
		String params = request.getParameter("args");
		Map<String, Object> paramMap = new HashMap<String, Object>();
		
		if(params != null) {
			StringTokenizer tokenizer = new StringTokenizer(params, "@@");
			while(tokenizer.hasMoreElements()) {
				StringTokenizer tokenizer2 = new StringTokenizer(tokenizer.nextToken(), "\\|\\|\\|\\|");
				int param = Integer.parseInt((String) tokenizer2.nextElement());
				String value = tokenizer2.nextToken();
				
				ReportParam reportParam = report.getParam(param);
				paramMap.put(reportParam.getField(), value);
			}
		}	
		 
		IFileReporteExporter exporter = new JasperExporter();
		return exporter.export(null, report.getDescription(), paramMap, reportDataAccess.getConnection(report), report.getName());
	}
	
	StreamResponse onActionFromExportCsv() {
		List<Object> args= new ArrayList<Object>();		
		String params = request.getParameter("args");

		if(params != null) {
			StringTokenizer tokenizer = new StringTokenizer(params, "@@");
			while(tokenizer.hasMoreElements()) {
				StringTokenizer tokenizer2 = new StringTokenizer(tokenizer.nextToken(), "\\|\\|\\|\\|");
				tokenizer2.nextElement();
				args.add(tokenizer2.nextElement());
			}
		}		

		List<Map<String, Object>> rows;
		try {
			rows = reportDataAccess.executeFullReport(report, args.toArray());
			IFileReporteExporter exporter = new CsvExporter();
			return exporter.export(rows, null, null, null, report.getName());			
		} catch (Exception e) {
			e.printStackTrace();
			setError(e.getMessage());
		}
		
		return null;
	}
	
	public boolean getOpen() {
		if(param.getDataType().equals("DATE") || param.getDataType().equals("TIMESTAMP")) {
			return false;
		}
		return true;
	}
}
